import axios from 'axios'
import type { Method, AxiosRequestConfig } from 'axios'
import type { Data } from './types'

// 创建一个 axios 实例
const service = axios.create({
  // baseURL: import.meta.env.BASE_URL,
  baseURL: 'https://api-hot.efefee.cn',
  timeout: 5000
})

service.interceptors.request.use((config) => {
  // 用于设置token
  // config.headers.token = getToken()
  return config
})

service.interceptors.response.use(
  (response) => {
    // 简化 返回的值
    return response.data
  },
  (error) => {
    let msg = ''
    const status = error.response.status
    // TODO: 重写错误处理, 并且明确触发时机
    switch (status) {
      case 401:
        msg = 'token过期'
        break
      case 403:
        msg = '无权访问'
        break
      case 404:
        msg = '未找到服务'
        break
      case 500:
        msg = '服务器出现问题'
        break
      default:
        msg = '无网络'
    }
    console.log('触发响应拦截时的错误信息=>', msg)
    // 返回了一个被拒绝的 Promise，以便将错误信息传递给调用方。
    // 目的: 将错误信息传播出去，以便调用方能够进一步处理错误.
    return Promise.reject(error)
  }
)

/** 不直接 return 出去 service */

// 此处的 这个 T, 是确定接口返回值res中 data 的类型
const http = <T>(
  url: string,
  method: Method,
  submitData?: any, // 此时是接口的参数类型, 可能各种各样的都有
  config?: AxiosRequestConfig
) => {
  // 此处看源码: request的 第二个类型参数是 AxiosResponse: ax 的返回类型, 此时是固定的, 所以是 Data
  //    但是data所包含的返回值是不确定的, 需要手动确定类型
  // request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
  return service.request<T, Data<T>>({
    url,
    method,
    [method.toLocaleLowerCase() === 'get' ? 'params' : 'data']: submitData,
    ...config
  })
}

export default http
